package jzh.cloud.user.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jzh.cloud.common.entity.Goods;
import jzh.cloud.common.entity.User;
import jzh.cloud.common.redisKey.RedisKey;
import jzh.cloud.user.mapper.GoodsMapper;
import jzh.cloud.user.mapper.UserMapper;
import jzh.cloud.user.service.UserService;
import lombok.AllArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@DubboService
@AllArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final RocketMQTemplate rocketMQTemplate;

    private final StringRedisTemplate stringRedisTemplate;

    private final GoodsMapper goodsMapper;

    @Override
    public User getUser(Long id) {
        //1. 获取当前日期。
        LocalDateTime now = LocalDateTime.now();
        //2. 获取当前日期中的  年和月
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        //3. 拼接key  (当前用户id + 年月)
        String key = RedisKey.USER_SIGN_KEY + id + keySuffix;
        //4. 获取今天是当月的第几天
        int dayOfMonth = now.getDayOfMonth();
        stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);

        Boolean bit1 = stringRedisTemplate.opsForValue().setBit(key, dayOfMonth, true);
        Boolean bit2 = stringRedisTemplate.opsForValue().setBit(key, dayOfMonth + 1, true);
        Boolean bit3 = stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 2, true);

        //连续签到数量
        List<Long> longs = stringRedisTemplate.opsForValue().bitField(key, BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth + 2)).valueAt(0));

        int count = 0;
        Long aLong = longs.get(0);

        while (true) {
            if ((aLong & 1) == 0) {
                break;
            } else {
                count++;
            }
            aLong >>>= 1;
        }
        rocketMQTemplate.syncSend("pineapple-user", "测试mq");

        Long increment = stringRedisTemplate.opsForValue().increment(RedisKey.USER_SIGN_KEY + id, 1);

        //本月签到数量
        Long execute = stringRedisTemplate.execute((RedisCallback<Long>) connection -> connection.bitCount(key.getBytes()));

        //签到信息
        List<Long> longList = stringRedisTemplate.execute((RedisCallback<List<Long>>) cbk -> cbk.bitField(key.getBytes(), BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth + 2)).valueAt(0)));

        return baseMapper.selectById(id);
    }

    @Override
    public String redisGeo() {
        List<RedisGeoCommands.GeoLocation<String>> locations1 = new ArrayList<>(15);
        // 写入redis GEOADD key 经度 维度 member
        locations1.add(new RedisGeoCommands.GeoLocation(
                "万象汇",
                new Point(120.93407, 31.38789)));
        locations1.add(new RedisGeoCommands.GeoLocation(
                "家",
                new Point(120.95929, 31.37707)));
        locations1.add(new RedisGeoCommands.GeoLocation(
                "苏州北站",
                new Point(120.64995, 31.42810)));
        stringRedisTemplate.opsForGeo().add(RedisKey.SHOP_GEO + "1", locations1);

        List<RedisGeoCommands.GeoLocation<String>> locations2 = new ArrayList<>(15);
        // 写入redis GEOADD key 经度 维度 member
        locations2.add(new RedisGeoCommands.GeoLocation(
                "金鹰",
                new Point(120.97962, 31.38221)));
        locations2.add(new RedisGeoCommands.GeoLocation(
                "昆城",
                new Point(120.96071, 31.37041)));
        stringRedisTemplate.opsForGeo().add(RedisKey.SHOP_GEO + "2", locations2);

        Distance distance = stringRedisTemplate.opsForGeo().distance(RedisKey.SHOP_GEO + "1", "万象汇", "家");
        List<Point> pointList = stringRedisTemplate.opsForGeo().position(RedisKey.SHOP_GEO + "2", "金鹰");

        Circle circle = new Circle(new Point(120.95929, 31.37707), 300000);
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
                .includeDistance().includeCoordinates().sortAscending().limit(10);
        GeoResults<RedisGeoCommands.GeoLocation<String>> radius = stringRedisTemplate.opsForGeo().radius(RedisKey.SHOP_GEO + "1", circle, args);

        return null;
    }

    @Override
    public String createUser(User user) {
        int insert = baseMapper.insert(user);
        return insert + "";
    }

    @Override
    public String createGoods(Goods goods) {
        int insert = goodsMapper.insert(goods);
        return insert + "";
    }
}
